import io
import os
import uuid
from typing import Dict, Union, Optional, Tuple

import requests
import numpy as np
from fastapi import HTTPException, UploadFile, File
from fastapi.responses import JSONResponse, Response
from PIL import Image
from app.setting import settings

class ToSvgAPI:
    def __init__(self):
        self.static_path = f"{settings.STATIC_PATH}/images"
        self.static_dir = f"{settings.STATIC_DIR}/images"
        # 确保静态资源目录存在
        os.makedirs(self.static_dir, exist_ok=True)
        
    def handle(self, url: str, type: str = "json"):
        """
        处理图片转svg请求
        
        Args:
            url: 图片url
            type: 输出格式，默认为json
            
        Returns:
            转换后的svg字符串或JSON响应
        """
        try:
            # 下载图片
            response = requests.get(url, timeout=10)
            if response.status_code != 200:
                return self._error_response("无法下载图片", 400)
            
            # 处理图片
            input_image = Image.open(io.BytesIO(response.content))
            return self._process_and_return(input_image, type)
                
        except Exception as e:
            return self._error_response(f"处理图片时出错: {str(e)}", 500)
    
    async def handle_upload(self, file: UploadFile, type: str = "json"):
        """
        处理上传图片转svg请求
        
        Args:
            file: 用户上传的图片文件
            type: 输出格式，默认为json
            
        Returns:
            转换后的svg字符串或JSON响应
        """
        try:
            # 读取上传的图片
            contents = await file.read()
            
            # 处理图片
            input_image = Image.open(io.BytesIO(contents))
            return self._process_and_return(input_image, type)
                
        except Exception as e:
            return self._error_response(f"处理图片时出错: {str(e)}", 500)
    
    def _process_and_return(self, input_image: Image.Image, type: str) -> Union[JSONResponse, Response]:
        """
        处理图片并根据类型返回结果
        
        Args:
            input_image: 输入图片
            type: 返回类型
            
        Returns:
            处理结果
        """
        # 转换图片为SVG
        svg_data = self.convert_to_svg(input_image)
        
        # 根据type返回不同格式
        if type.lower() == "json":
            # 保存SVG并返回JSON
            svg_path, svg_url = self._save_svg(svg_data)
            return JSONResponse({
                "success": True,
                "data": {
                    "url": svg_url
                },
                "code": 200
            }, status_code=200, media_type="application/json; charset=utf-8")
        elif type.lower() == "svg":
            # 直接返回SVG
            return Response(
                content=svg_data,
                media_type="image/svg+xml",
                headers={
                    "Content-Disposition": "attachment; filename=converted.svg"
                },
                status_code=200
            )
        else:
            return self._error_response("不支持的返回类型", 400)
    
    def _error_response(self, message: str, status_code: int) -> JSONResponse:
        """
        生成错误响应
        
        Args:
            message: 错误信息
            status_code: 状态码
            
        Returns:
            JSON格式的错误响应
        """
        return JSONResponse({
            "success": False,
            "data": {
                "msg": message
            },
            "code": status_code
        }, status_code=status_code, media_type="application/json; charset=utf-8")
    
    def convert_to_svg(self, image: Image.Image) -> str:
        """
        将PIL图像转换为SVG
        
        Args:
            image: PIL图像对象
            
        Returns:
            SVG字符串
        """
        # 确保图片是RGBA模式
        if image.mode != 'RGBA':
            image = image.convert('RGBA')
        
        # 生成SVG
        svg_data = self._generate_svg(image)
        
        return svg_data
    
    def _generate_svg(self, image: Image.Image) -> str:
        """
        生成SVG字符串（逐像素生成）
        
        Args:
            image: PIL图像对象
            
        Returns:
            SVG字符串
        """
        width, height = image.size
        data = image.load()
        
        # SVG头部
        svg = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n'
        svg += f'<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="{width}" height="{height}" viewBox="0 0 {width} {height}">\n'
        
        # 逐像素生成SVG
        for y in range(height):
            for x in range(width):
                rgba = data[x, y]
                rgb = '#%02x%02x%02x' % rgba[:3]
                if rgba[3] > 0:
                    svg += f'<rect width="1" height="1" x="{x}" y="{y}" fill="{rgb}" fill-opacity="{rgba[3] / 255.0:.2f}" />\n'
        
        # SVG尾部
        svg += '</svg>'
        
        return svg
    
    def _save_svg(self, svg_data: str) -> Tuple[str, str]:
        """
        保存SVG并返回路径和URL
        
        Args:
            svg_data: SVG字符串
            
        Returns:
            (文件路径, SVG URL)的元组
        """
        # 生成唯一文件名
        filename = f"{uuid.uuid4()}.svg"
        file_path = os.path.join(self.static_dir, filename)
        
        # 保存SVG
        with open(file_path, 'w', encoding='utf-8') as f:
            f.write(svg_data)
        
        # 生成URL
        svg_url = f"{self.static_path}/{filename}"
        
        return file_path, svg_url